<?php

use EasyWeChat\Kernel\Messages\Text;
use EasyWeChat\Kernel\Messages\Image;
use EasyWeChat\Kernel\Messages\Video;
use EasyWeChat\Kernel\Messages\Voice;
use EasyWeChat\Kernel\Messages\News;
use EasyWeChat\Kernel\Messages\NewsItem;
use EasyWeChat\Kernel\Messages\Article;
use EasyWeChat\Kernel\Messages\Media;
use EasyWeChat\Kernel\Messages\Raw;
use EasyWeChat\Kernel\Messages\Voice as SendVoice;
use Monolog\Logger;


class HandleController extends WxBaseController
{
	/**
	 * 消息与事件接收
	 * @param $appId
	 */
	public function eventAction($appId)
	{
		$officialAccount = self::$open->officialAccount($appId);
		$server = $officialAccount->server;
		$server->push(function ($message) use ($appId, $officialAccount) {
			//全网测试
			if ($appId === 'wx570bc396a51b8ff8') {
				return $this->checkTest($message);
			}
			//更新活跃时间
			//事件另外处理
			$openId = $message['FromUserName'];
			if ($message['MsgType'] !== 'event') {
				$this->upActive($appId, $openId, $message['MsgType']);
			}
			//业务逻辑
			switch (strtolower($message['MsgType'])) {
				case 'event':
					if (strtolower($message['Event']) !== 'templatesendjobfinish') {
						$this->upActive($appId, $openId, $message['Event']);
					}
					switch (strtolower($message['Event'])) {
						case 'subscribe':
						    return $this->subscribe($message, $appId);
							break;
						case 'unsubscribe':
							$this->unsubscribe($message, $appId);
							break;
						case "click":
                            $eventKey = $message['EventKey'];
                            $this->person_menu_handle($eventKey,$appId,$openId,$officialAccount);
						    return 'success';
//							$message = new Text($text);
//							//自定义菜单事件
//							return $message;
							break;
                        case "templatesendjobfinish":
                            return 'success';
                            break;
                        case "view":
                            PersonalMenuClickLog::add(['app_id'=>$appId,'open_id'=>$openId,'type'=>'jump_view']);
                            return 'success';
                            break;
						default:
							$message = new Text(json_encode($message, JSON_UNESCAPED_UNICODE));
							//自定义菜单事件
							return $message;
							break;
					}
					return 'success';
					break;
				case 'text':
				    $res = $this->keyWord($openId, $appId, $message['Content']);
				    if(!$res){
                        $this->getMsg('text',$Event='',$appId,$openId);
                    }
				    return 'success';
					break;
				case 'image':
                    $this->getMsg('image',$Event='',$appId,$openId);
					return 'success';
					break;
				case 'voice':
                    $this->getMsg('voice',$Event='',$appId,$openId);
					return 'success';
					break;
				case 'video':
					return 'success';
					break;
				case 'location':
					return 'success';
					break;
				case 'link':
					return 'success';
					break;
				case 'file':
					return 'success';
				default:
					return 'success';
					break;
			}

		});
		$server->serve()->send();
		$this->view->disable();
	}

	/**
	 * 全网发布检测逻辑
	 * @param $message
	 * @return string
	 */
	private function checkTest($message)
	{
	    $monolog = new MonologHelper();
	    $log = $monolog->log('checkTest','checkTest');
		switch ($message['MsgType']) {
			case 'event':
				return $message['Event'] . 'from_callback';
				break;
			case 'text':
				$content = $message['Content'];
				if ($content === 'TESTCOMPONENT_MSG_TYPE_TEXT') {
					return 'TESTCOMPONENT_MSG_TYPE_TEXT_callback';
				}
				if (strpos($content, 'QUERY_AUTH_CODE:') === 0) {
					$auth_code = substr($content, 16);
					$authorization = self::$open
						->handleAuthorize($auth_code);
					$appInfo = $authorization["authorization_info"];
					$refreshToken = $appInfo["authorizer_refresh_token"];
					$authorizer_appid = 'wx570bc396a51b8ff8';
					$official_account_client = self::$open
						->officialAccount($authorizer_appid, $refreshToken);
					$content = $auth_code . '_from_api';
					$openId = $message['FromUserName'];

					$result = $official_account_client
						->customer_service
						->message($content)
						->to($openId)
						->send();
                    $log->info($openId.'-'.$content);
                    $log->info(json_encode($result));
					return '';
				}
				return 'success';
				break;
			default:
				return 'success';
				break;

		}
	}

	/**
	 * 关注事件
	 * @param $message
	 * @param $appId
	 * @return string|array
	 */
	private function subscribe($message, $appId)
	{
		$openId = $message['FromUserName'];
		//加入粉丝表
		$user = Users::findFirst("app_id = '{$appId}' and open_id = '{$openId}'");
		if (!$user) {
			$user = new Users();
		}
		$refreshToken = $this->getRefreshToken($appId);
		if (!$refreshToken) {
			return 'success';
		}
		$user->app_id = $appId;
		$user->open_id = $openId;
		$user->subscribe_time = date("Y-m-d H:i:s");
		$user->is_subscribe = 1;
		$user->save();
		$officialAccount = self::$open->officialAccount($appId, $refreshToken);
		$userInfo = $officialAccount->user->get($openId);
		$UserInfo = new UserInfo();
		$exit = $UserInfo::findFirst("openid='{$openId}'");
		if (!$exit) {
			$UserInfo->save($userInfo);
		}


		//关注回复消息
		$msgs = $this->getMsgs($appId, 'subscribe');
		if (count($msgs) > 0) {
			$items = [];
			foreach ($msgs as $msg) {
				$userName = '';//处理名称替换

				if ($msg->type === 'text' && strpos($msg->desc, '${name}') !== false) {

					$userInfo = $this->getUserInfo($appId, $openId, $officialAccount);
					if ($userInfo && isset($userInfo['nickname'])) {
						$userName = $userInfo['nickname'];
					}
				}

				if (in_array($msg->type, ['image', 'voice', 'video'])) {

					$mediaId = $this->getMediaId($officialAccount, $msg->img_url, $msg->type);
					if (!$mediaId) {
						return false;
					}
					$msg->img_url = $mediaId;
				}

				//图文图片地址
				if ($msg->type === 'news') {
					$msg->img_url = BASE_URL . $msg->img_url;
				}

				$returnMsg = MsgHelper::createMsg($msg->type, $msg, $userName);
				if ($msg->type === 'news') {
					$items[] = $returnMsg;
				} else {
					return $returnMsg;
				}
			}
			if (!empty($items)) {
				return new News($items);
			}
		}
		return 'success';
	}

	public function sendKfMsg($open_id,$app_id,$msg,$msg_type)
    {
        $all = [
            '010666593026240133',       //杨才俊    13757619801
            '03133136132496',    //卢仙红  15258838059
            "18454224221222463",       //陈璇  18143464872
            "063644012426073849",         //李倩娴  18758228105
            '04615943681257639',     //高灿
            '0150606863989551'      //程刚
        ];

        try{
            $refreshToken = $this->getRefreshToken($app_id);
            if (!$refreshToken) {
                return false;
            }
            $officialAccount = self::$open->officialAccount($app_id, $refreshToken);
            $userInfo = UserInfo::findFirst("openid='{$open_id}'");
            $nickname  = $userInfo->nickname;
            $appinfo = AuthorizedAppInfo::findFirst("app_id='{$app_id}'");
            $sendMsg = new SendMsg($this->db);
            foreach ($msg as $vo) {
                $type = $vo['type'];
                $res = false;
                switch ($type) {
                    case 'text':
                        $content = str_replace('{{name}}', $nickname, $vo['content']);
                        $res = $sendMsg->sendText($officialAccount, $content, $open_id);
                        break;
                    case 'poster':
                        $content = $vo['content'];
                        $res = $sendMsg->sendPoster($officialAccount, $open_id, $app_id, $content, $msg_type);
                        sleep(1);
                        break;
                    case 'voice':
                        $content = $vo['content'];
                        $res = $sendMsg->sendVoice($officialAccount, $open_id, $app_id, $content);
                        break;
                    case 'img_text':
                        $content = str_replace('{{name}}', $nickname, $vo['content']);
                        $content = json_decode($content, true);
                        $msg = [
                            'title' => $content['title'],
                            'description' => $content['desc'],
                            'url' => $content['url'],
                            'image' => 'http://' . $this->config->interface_domain . $content['img_url']
                        ];
                        $res = $sendMsg->sendNews($officialAccount, $msg, $open_id);
                        break;
                    case 'template':
                        $content = str_replace('{{name}}', $nickname, $vo['content']);
                        $content = json_decode($content, true);
                        $content = array_merge(['touser' => $open_id], $content['message']);
                        $res = $sendMsg->sendTemplate($officialAccount, $content);
                        break;
                }
                if($res && !$res['status']){
                    self::send(["content"=>date("Y-m-d H:i:s")."\r\n公众号：".$appinfo['nick_name']."\r\n关注自动回复消息发送失败\r\n消息：{{$type}}-handle\r\n接收人：".$nickname."\r\n请联系技术排查问题"],$all);
                }
            }
        }catch (Exception $exception){
            MyLog::setLog([$exception->getMessage(),$exception->getFile(),$exception->getLine()], 'handle_error', Logger::INFO, '', '', PUBLIC_PATH . '/log/handle_sub_msg/task_error.log');
        }
    }

	/**
	 * 取关事件
	 * @param $message
	 * @param $appId
	 */
	private function unsubscribe($message, $appId)
	{
		$openId = $message['FromUserName'];
		//更改粉丝表状态
		$user = Users::findFirst("app_id = '{$appId}' and open_id = '{$openId}'");
		if (!$user) {
			$user = new Users();
		}
		$user->app_id = $appId;
		$user->open_id = $openId;
		$user->is_subscribe = 0;
		$user->save();
	}

	public function menu($officialAccount, $message, $appId)
	{
		$openId = $message['FromUserName'];
		$message = new Text('Hello world!');

		$result = $officialAccount->customer_service->message($message)->to($openId)->send();
		return "success";

	}

	/**
	 * 更新活跃时间
	 * @param $appId
	 * @param $openId
	 * @param $event
	 */
	private function upActive($appId, $openId, $event)
	{
		$event = strtolower($event);
		$active = ActiveUsers::findFirst("app_id='{$appId}' and open_id='{$openId}' and event='{$event}'");
		if (!$active) {
			$active = new ActiveUsers();
		}
		$active->app_id = $appId;
		$active->open_id = $openId;
		$active->event = $event;
		$active->active_time = date('Y-m-d H:i:s');
		$active->save();
	}


	/**
	 * 关键词回复逻辑
	 * @param $appId
	 * @param $openId
	 * @param $word
	 * @return string
	 */
	private function keyWord($openId, $appId, $word)
	{
		try {
            $match = $this->db->fetchAll("select kw.word as word,kw.match from key_word as kw left join key_word_message as km on kw.app_id=km.app_id and kw.kid=km.id where kw.app_id='{$appId}' and '{$word}' like concat('%',kw.word,'%') and km.enabled=1");
            if(!empty($match)){
                foreach ($match as $val){
                    if($val['match'] ==1){
                        if($word == $val['word']){
                            $where = "km.app_id='{$appId}' and kw.word='{$word}' and km.enabled=1 and kw.match=1";
                        }else{
                            continue;
                        }
                    }elseif($val['match'] == 2){
                        $where = "kw.app_id='{$appId}' and '{$word}' like concat('%',kw.word,'%') and km.enabled=1 and kw.match = 2 group by kw.kid";
                    }
                }
            }else{
                return false;
                $where = '15 =16';
            }

            $workIds = $this->db->fetchAll("select kw.kid,kw.word,km.app_id from key_word as kw left join key_word_message as km on kw.app_id=km.app_id and kw.kid=km.id where {$where} ");
            if (count($workIds) > 0) {
                $refreshToken = $this->getRefreshToken($appId);
                if (!$refreshToken) {
                    return false;
                }
                $officialAccount = self::$open->officialAccount($appId, $refreshToken);
                $userInfo = $this->getUserInfo($appId, $openId, $officialAccount);

                foreach ($workIds as $workId){
                        $key_word_content = KeyWordContent::find(
                        [
                            'conditions' => "key_word_message_id = '{$workId['kid']}'",
                        ]
                    );
                    if($key_word_content){
                        $key_word_content = $key_word_content->toArray();
                        $group_num = time() . rand(10000,99999);
                        $create_time = date('Y-m-d H:i:s',time());
                        foreach ($key_word_content as $val){
                            $key_word_task = new KeyWordTask();
                            $key_word_task->app_id = $appId;
                            $key_word_task->open_id = $openId;
                            $key_word_task->nickname = $userInfo['nickname'];
                            $key_word_task->msg_type = $val['type'];
                            $key_word_task->msg_content = $val['content'];
                            $key_word_task->group_num = $group_num;
                            $key_word_task->create_time = $create_time;
                            $res = $key_word_task->save();
                            if(!$res){
                                foreach ($key_word_task->getMessages() as $message) {
                                    MyLog::setLog([$message->getMessage()], $key_word_task->app_id . "关键字消息计划任务添加失败", Logger::INFO, '', '', PUBLIC_PATH . '/log/sub_msg/' . $key_word_task->app_id . "_key_word_task_error.log");
                                }
                            }
                        }
                    }
                }
            }
			return 'success';
		} catch (Exception $e) {
			MyLog::setLog([$e->getMessage(), $e->getFile(), $e->getLine(),$e->getCode()], 'exception', Logger::INFO, '', '', PUBLIC_PATH . "/log/" . __CLASS__ . "/" . date("Ymd") . "/" . __FUNCTION__ . "_exception.log");
		}
	}

	/**
	 * 关注延时海报消息发送   2019-11-28
	 */
	public function addDelayMessage($app_id, $open_id)
	{
		$task = new DelayPosterMsgTask();
		$task->app_id = $app_id;
		$task->open_id = $open_id;
		$task->send_time = time() + 10;
		$task->status = 0;
		$task->create_at = date("Y-m-d H:i:s");
		$res = $task->save();
	}

	/**
	 * 自定义关注回复   2019-12-04
	 * @param $sub_msg
	 * @param $openid
	 * @param $userInfo
	 * @return string
	 */
	public function sub_msg($sub_msg, $openid, $userInfo)
	{
		try {
			$exit = SubMsgTask::findFirst("app_id='{$sub_msg->app_id}' and openid='{$openid}' and status=0");
			if (!$exit) {
				$sub_msg_task = new SubMsgTask();
				$sub_msg_task->app_id = $sub_msg->app_id;
				$sub_msg_task->openid = $openid;
				$sub_msg_task->nickname = $userInfo['nickname'];
				$sub_msg_task->status = 0;
				$sub_msg_task->create_at = date("Y-m-d H:i:s");
				$res = $sub_msg_task->save();
				if (!$res) {
					foreach ($sub_msg_task->getMessages() as $message) {
						MyLog::setLog([$message->getMessage()], $sub_msg->app_id . "计划任务添加失败", Logger::INFO, '', '', PUBLIC_PATH . '/log/sub_msg/' . $sub_msg->app_id . "_sub_msg_task_error.log");
					}

				} else {
					MyLog::setLog([$sub_msg_task], $sub_msg->app_id . "计划任务添加成功", Logger::INFO, '', '', PUBLIC_PATH . '/log/sub_msg/' . $sub_msg->app_id . "_sub_msg_task_success.log");
				}
			}else{
				MyLog::setLog([$exit, "info" => "任务重复添加"], $sub_msg->app_id . "计划任务添加失败", Logger::INFO, '', '', PUBLIC_PATH . '/log/sub_msg/' . $sub_msg->app_id . "_sub_msg_task_error.log");
			}

		} catch (Exception $exception) {
			MyLog::setLog([$exception->getMessage(), $exception->getFile(), $exception->getLine()], $sub_msg->app_id . "计划任务添加异常", Logger::INFO, '', '', PUBLIC_PATH . '/log/sub_msg/' . $sub_msg->app_id . "_exception.log");
		}


//		$refreshToken = $this->getRefreshToken($sub_msg->app_id);
//
//		if (!$refreshToken) {
//			return false;
//		}
//		$result = [];
//		$officialAccount = self::$open->officialAccount($sub_msg->app_id, $refreshToken);
//		if ($sub_msg->msg1 != "") {
//			$message = new Text(str_replace('{{name}}',$userInfo['nickname'],$sub_msg->msg1));
//			$result['msg1'] = $officialAccount->customer_service->message($message)->to($openid)->send();
//		}
//		if ($result['msg1']['errcode'] == 0) {
//
//			if ($sub_msg->msg2 != '') {
//				$img_info = $this->db->fetchAll("select img_path from img_list where img_id='{$sub_msg->msg2}' and is_delete=0");
//				$img_path = array_column($img_info, "img_path");
//				$num = rand(0, count($img_path)-1);
//				$img_url = $img_path[$num];
//				$mediaId = $this->getMediaId($officialAccount, $img_url, 'image');
//				if (!$mediaId) {
//					return false;
//				}
//				$message = new Image($mediaId);
//
//				$result['msg2'] = $officialAccount->customer_service->message($message)->to($openid)->send();
//			}
//		}
//		if ($result['msg2']['errcode'] == 0) {
//			sleep(3);
//			if ($sub_msg->msg3 != '') {
//				$message = new Text(str_replace('{{name}}',$userInfo['nickname'],$sub_msg->msg3));
//				$result['msg3'] = $officialAccount->customer_service->message($message)->to($openid)->send();
//			}
//		}
//		MyLog::setLog([$result,$userInfo['nickname'],$userInfo], $sub_msg->app_id, Logger::INFO, '', '', PUBLIC_PATH . '/log/sub_msg/' . $sub_msg->app_id . "_sub_msg.log");
	}

    /**
     * 获取是否设置被动前回复或被动回复
     * @param $appId
     * @param string $type
     * @return bool
     */
    public function get_passive_reply($appId,$type='sub_msg')
    {
        if($type == 'sub_msg'){
            $passive_reply = SubMsg::findFirst("app_id='{$appId}' and enabled = 1 and passive_reply is not null and passive_reply != '0' and passive_reply != '1' and passive_reply != 'null'");
            if($passive_reply){
                return $passive_reply->toArray();
            }else{
                return false;
            }
        }
    }

    /**
     * 被动回复前回复客服消息
     * @param $appId
     * @param $userInfo
     * @param $passive_reply_before
     * @param $officialAccount
     * @return bool
     */
    public function passive_replay_before($appId,$userInfo,$passive_reply_before,$officialAccount)
    {
        $all = [
            '010666593026240133',       //杨才俊    13757619801
            '03133136132496',    //卢仙红  15258838059
            "18454224221222463",       //陈璇  18143464872
            "063644012426073849",         //李倩娴  18758228105
            '04615943681257639',     //高灿
            '0150606863989551'      //程刚
        ];
        $material = '';

        try{
            $list = $passive_reply_before;
            if (!empty($list)) {
                $info['app_id'] = $appId;
                $info['openid'] = $userInfo['openid'];
                $info['nickname'] = $userInfo['nickname'];
                $info['nick_name'] = AuthorizedAppInfo::findFirst("app_id='{$appId}'")->nick_name;
                $list['nickname'] = $userInfo['nickname'];
                $list['openid'] = $userInfo['openid'];
                $result = [];

                //先上传永久素材
                if ($list['msg2'] != ""){
                    //根据网页授权保证网页与关注回复二维码统一
                    $authDuplicateRemoval = false;
//                        $qr_cache_key = 'auth-' . $info['app_id'] . '-' . $info['openid'];
//                        if($redis->exists($qr_cache_key)) {
//                            $qr_id = $redis->get($qr_cache_key);
//                            $img_info = $this->db->fetchAll("select i.id,i.img_path,qr.wx from img_list as i left join qr_info as qr on i.qr_id=qr.id where i.img_id='{$list['msg2']}' and i.qr_id = '{$qr_id}' and i.is_delete=0 and qr.is_delete=0");
//                            if(!empty($img_info)){
//                                $authDuplicateRemoval = true;
//                            }
//                        }
                    if(!$authDuplicateRemoval){
                        $img_info = $this->db->fetchAll("select i.id,i.img_path,i.qr_id,qr.wx from img_list as i left join qr_info as qr on i.qr_id=qr.id where i.img_id='{$list['msg2']}' and i.is_delete=0 and qr.is_delete=0");
                    }

                    //二维码循环展示
                    $count = count($img_info);
                    $redis_num_key = $info['app_id'] . '-qr_num_count';
                    $now_num_key = $info['app_id'] . '-now_num_key';
                    $this->redis->set($redis_num_key, $count);
                    if($this->redis->exists($now_num_key)) { //是否存在缓存
                        $now_num = $this->redis->get($now_num_key);
                        if($now_num >= $count){
                            $now_num = 1;
                        }else{
                            $now_num++;
                        }
                    }else{
                        $now_num = 1;
                    }
                    $this->redis->set($now_num_key, $now_num);
                    $num = $now_num - 1;

                    $qr_id = $img_info[$num]['qr_id'];
                    $qr_cache_key = 'auth-' .  $info['app_id'] . '-' .  $info['openid'];
                    $this->redis->set($qr_cache_key, $qr_id);

                    $img_url =PUBLIC_PATH."/". $img_info[$num]['img_path'];
                    $wxh_id = $img_info[$num]['wx'];
                    ImgQrDetails::saveLog($list['app_id'],$list['openid'],$img_info[$num]['id'],'subscribe');
                    $exit = Material::findFirst("app_id='{$list['app_id']}' and path='{$img_url}'");
                    if(!$exit){
                        $res = UploadToWeixin::uploadImage($officialAccount,$img_url,$list['app_id']);
                        if(!$res){
//                            $this->db->execute("update sub_msg_task set status=4,update_at='".date("Y-m-d H:i:s")."' where id='{$list['id']}'");
                            self::send(["content"=>date("Y-m-d H:i:s")."\r\n公众号：".$list['nick_name']."\r\n关注自动回复消息发送失败(永久素材上传失败,尝试第二次上传)\r\n消息：二维码图片2-handle\r\n接收人：".$list['nickname']."\r\n请联系技术排查问题"],$all);
                            MyLog::setLog(["app_id"=>$list['app_id'],"to_user"=>$list['nickname'],'img_url'=>$img_url,$list], $list['app_id'],Logger::INFO, '', '', PUBLIC_PATH . '/log/handle_sub_msg/' . $list['app_id'] . "_material_error.log");
                            return false;
                        }else{
                            $material = $res['media_id'];
                        }
                    }else{
                        $material = $exit->media_id;
                    }
                }
//                $this->db->execute("update sub_msg_task set status=1,update_at='".date("Y-m-d H:i:s")."' where id='{$list['id']}'");


                if ($list['msg1'] != "") {
                    $msg1 = str_replace('{{name}}',$list['nickname'],$list['msg1']);
                    $msg1= str_replace('{{wxh_id}}',$wxh_id,$msg1);
                    $message = new Text($msg1);
                    $result['msg1'] = $officialAccount->customer_service->message($message)->to($list['openid'])->send();
                    if($result['msg1']['errcode'] != 0&&$result['msg1']['errcode']!='45015'){
                        $info['msg']['msg1']=$msg1;
                        self::send(["content"=>date("Y-m-d H:i:s")."\r\n公众号：".$list['nick_name']."\r\n关注自动回复消息发送失败\r\n消息：文字消息1-handle\r\n接收人：".$list['nickname']."\r\n请联系技术排查问题"],$all);
//                        $this->db->execute("update sub_msg_task set status=2,update_at='".date("Y-m-d H:i:s")."' where id='{$list['id']}'");
                    }
                }

                if ($list['msg2'] != "") {
                    $message = new Image($material);
                    $result['msg2'] = $officialAccount->customer_service->message($message)->to($list['openid'])->send();
                    if($result['msg2']['errcode'] != 0&&$result['msg2']['errcode']!='45015'){
                        $info['msg']['msg2'] = $material;
                        self::send(["content"=>date("Y-m-d H:i:s")."\r\n公众号：".$list['nick_name']."\r\n关注自动回复消息发送失败\r\n消息：二维码图片2-handle\r\n接收人：".$list['nickname']."\r\n请联系技术排查问题"],$all);
//                        $this->db->execute("update sub_msg_task set status=3,update_at='".date("Y-m-d H:i:s")."' where id='{$list['id']}'");
                    }
                }


                if ($list['msg3'] != '') {
                    sleep(3);
                    $appVoice = AppVoice::findFirst([
                        'conditions' => 'voice_id = ' .  $list['msg3'] . " and app_id = '" . $info['app_id'] . "'",
                        'columns' => 'media_id'
                    ]);
                    $message = new SendVoice($appVoice->media_id);
                    $result['msg3'] = $officialAccount->customer_service->message($message)->to($list['openid'])->send();
                    if($result['msg3']['errcode'] != 0 &&$result['msg3']['errcode']!='45015'){
                        $info['msg']['msg3']=$appVoice->media_id;
                        self::send(["content"=>date("Y-m-d H:i:s")."\r\n公众号：".$list['nick_name']."\r\n关注自动回复消息发送失败\r\n消息：语音消息3-handle\r\n接收人：".$list['nickname']."\r\n请联系技术排查问题"],$all);
//                        $this->db->execute("update sub_msg_task set status=4,update_at='".date("Y-m-d H:i:s")."' where id='{$list['id']}'");
                    }
                }
                MyLog::setLog(["to_user"=>$list['nick_name'],$result,$list], $list['app_id'], Logger::INFO, '', '', PUBLIC_PATH . '/log/handle_sub_msg/' . $list['app_id'] . "_sub_msg_send_success.log");
            }
        }catch (Exception $exception){
            print_r($exception->getMessage()).PHP_EOL;
            print_r($exception->getCode()).PHP_EOL;
            print_r($exception->getFile()).PHP_EOL;
            MyLog::setLog([$exception->getMessage(),$exception->getFile()], 'handle_error', Logger::INFO, '', '', PUBLIC_PATH . '/log/handle_sub_msg/task_error.log');
        }
    }

    /**
     * @param $msg
     * @param string $userid_list
     * @return bool
     */
    private function send($msg, $userid_list = "")
    {

        try {

            if ($userid_list == "") {
                //测试通知自己
//                $userid_list = [
//                    '0150606863989551'
//                ];
                $userid_list = [
                    '010666593026240133',       //杨才俊    13757619801
                    '03133136132496',    //卢仙红  15258838059
                    "18454224221222463",       //陈璇  18143464872
                    "063644012426073849",         //李倩娴  18758228105
                    '04615943681257639',     //通知自己
                    '0150606863989551'      //程刚
                ];
            }
            $dingTalk = new DingTalk();
            $dingTalk->sendCorpMsgForMsgTask(json_encode($msg, JSON_UNESCAPED_UNICODE), implode(',',$userid_list), false, false, 'text');

        } catch (Exception $exception) {
//            MyLog::setLog(["message"=>$exception->getMessage(),"file"=>$exception->getFile(),"line"=>$exception->getLine()], '自定义菜单-发送模板消息', Logger::INFO, '', '', PUBLIC_PATH . '/log/'.__CLASS__.'/' . date("Ymd") . '/' . __FUNCTION__ . ".log");
            print_r($exception->getMessage()) . PHP_EOL;
            print_r($exception->getFile()) . PHP_EOL;
            print_r($exception->getLine()) . PHP_EOL;
        }
    }


    /**
     * 自定义菜单事件处理
     * @param $eventKey
     * @param $appId
     * @param $openId
     */
    public function person_menu_handle($eventKey,$appId,$openId)
    {
        $refreshToken = $this->getRefreshToken($appId);
        if (!$refreshToken) {
            return false;
        }
        $officialAccount = self::$open->officialAccount($appId, $refreshToken);

        $eventKey = explode('-',$eventKey);
        $content = PersonalMenuContent::findFirst("personal_menu_id = '{$eventKey[1]}'");
        if($content && $content->content){

            if($eventKey[0] == 'send_template'){
                $userInfo = $this->getUserInfo($appId, $openId, $officialAccount);
                if ($userInfo && isset($userInfo['nickname'])) {
                    $userName = $userInfo['nickname'];
                }else{
                    $userName = '';
                }
                $content_str = str_replace('{{name}}',$userName,$content->content);
            }else{
                $content_str = $content->content;
            }
            $content = json_decode($content_str,true);
            $sendMsg = new SendMsg($this->db);
            $appinfo = AuthorizedAppInfo::findFirst("app_id='{$appId}'");
            switch ($eventKey[0]){
                case 'send_template':
                    PersonalMenuClickLog::add(['app_id'=>$appId,'open_id'=>$openId,'type'=>'send_template']);
                    $send_data = array_merge(['touser'=>$openId],$content['message']);
//                    if($appId == 'wxfc45d03609c87724'){
                    $res = $sendMsg->sendTemplate($officialAccount,$send_data);
                    if(!$res['status']){
                        $result = json_decode($res['msg'],true);
                        MyLog::setLog(["app_id"=>$appId,"result"=>$result['errmsg']], '自定义菜单-发送模板消息', Logger::INFO, '', '', PUBLIC_PATH . '/log/'.__CLASS__.'/' . date("Ymd") . '/' . __FUNCTION__ . ".log");
                        $this->send(["content"=>date("Y-m-d H:i:s")."\r\n公众号：".$appinfo->nick_name."\r\n自定义菜单-发送模板消息发送失败\r\n失败原因：".$result['errmsg']."\r\n请联系技术排查问题"]);
                    }
//                    }
//                    else{
//                        $this->sendTemplate($officialAccount,$appId,$send_data);
//                    }
                    break;
                case 'send_poster':
                    PersonalMenuClickLog::add(['app_id'=>$appId,'open_id'=>$openId,'type'=>'send_poster']);
                    $img_id = $content['img_id'];
//                    if($appId == 'wxfc45d03609c87724' || $appId == 'wx7857c14a5553bc2e'){
                    $res = $sendMsg->sendPoster($officialAccount,$openId,$appId,$img_id,$divisive='personal_menu');
                    if(!$res['status']){
                        $result = json_decode($res['msg'],true);
                        if(!$result){
                            $result['errmsg'] = '素材上传失败';
                        }
                        MyLog::setLog(["app_id"=>$appId,"result"=>$result['errmsg']], '自定义菜单-发送海报消息', Logger::INFO, '', '', PUBLIC_PATH . '/log/'.__CLASS__.'/' . date("Ymd") . '/' . __FUNCTION__ . ".log");
                        $this->send(["content"=>date("Y-m-d H:i:s")."\r\n公众号：".$appinfo->nick_name."\r\n自定义菜单-发送海报消息发送失败\r\n失败原因：".$result['errmsg']."\r\n请联系技术排查问题"]);
                    }
//                    }
//                    else{
//                        $this->sendPoster($officialAccount,$openId,$appId,$img_id);
//                    }
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 发送模板消息
     * @param $appId
     * @param $send_data
     * @return array
     */
    function sendTemplate($officialAccount,$appId,$send_data)
    {
        $result = $officialAccount->template_message->send($send_data);
        if($result['errcode'] !== 0){
            MyLog::setLog(["app_id"=>$appId,"result"=>$result['errmsg']], '自定义菜单-发送模板消息', Logger::INFO, '', '', PUBLIC_PATH . '/log/'.__CLASS__.'/' . date("Ymd") . '/' . __FUNCTION__ . ".log");
            self::send(["content"=>date("Y-m-d H:i:s")."\r\n公众号：".$appId."\r\n自定义菜单-发送模板消息发送失败\r\n失败原因：".$result['errmsg']."\r\n请联系技术排查问题"]);
        }
    }

    /**
     * 发送海报
     */
    public function sendPoster($officialAccount,$openId,$appId,$img_id)
    {
        //根据网页授权保证网页与关注回复二维码统一
        $authDuplicateRemoval = false;
        $qr_cache_key = 'auth-' . $appId . '-' . $openId;
        if($this->redis->exists($qr_cache_key)) {
            $qr_id = $this->redis->get($qr_cache_key);
            $img_info = $this->db->fetchAll("select i.id,i.img_path,i.qr_id,qr.wx from img_list as i left join qr_info as qr on i.qr_id=qr.id where i.img_id='{$img_id}' and i.qr_id = '{$qr_id}' and i.is_delete=0 and qr.is_delete=0");
            if(!empty($img_info)){
                $authDuplicateRemoval = true;
            }
        }

        if(!$authDuplicateRemoval){
            $img_info = $this->db->fetchAll("select i.id,i.img_path,i.qr_id,qr.wx from img_list as i left join qr_info as qr on i.qr_id=qr.id where i.img_id='{$img_id}' and i.is_delete=0 and qr.is_delete=0");
            //二维码循环展示
            $count = count($img_info);
            $redis_num_key = $appId . '-qr_num_count';
            $now_num_key = $appId . '-now_num_key';
            $this->redis->set($redis_num_key, $count);
            if($this->redis->exists($now_num_key)) { //是否存在缓存
                $now_num = $this->redis->get($now_num_key);
                if($now_num >= $count){
                    $now_num = 1;
                }else{
                    $now_num++;
                }
            }else{
                $now_num = 1;
            }
            $this->redis->set($now_num_key, $now_num);
            $num = $now_num - 1;
        }else{
            $num = 0;
        }

        $qr_id = $img_info[$num]['qr_id'];
        $qr_cache_key = 'auth-' .  $appId . '-' .  $openId;
        $this->redis->set($qr_cache_key, $qr_id);

        $img_url =PUBLIC_PATH . '/' .  $img_info[$num]['img_path'];
        ImgQrDetails::saveLog($appId,$openId,$img_info[$num]['id'],'personal_menu');
        $exit = Material::findFirst("app_id='{$appId}' and path='{$img_url}'");
        if(!$exit){
            $res = UploadToWeixin::uploadImage($officialAccount,$img_url,$appId);
            if(!$res){
                self::send(["content"=>date("Y-m-d H:i:s")."\r\n公众号：".$appId."\r\n自定义菜单海报消息发送失败(永久素材上传失败)\r\n消息：海报\r\n"."\r\n请联系技术排查问题"]);
                MyLog::setLog(["content"=>'永久素材上传失败'], '自定义菜单-发送海报', Logger::INFO, '', '', PUBLIC_PATH . '/log/'.__CLASS__.'/' . date("Ymd") . '/' . __FUNCTION__ . ".log");
                return false;
            }else{
                $material=$res['media_id'];
            }
        }else{
            $material=$exit->media_id;
        }

        $message = new Image($material);
        $result = $officialAccount->customer_service->message($message)->to($openId)->send();
        if($result['errcode'] != 0&&$result['errcode']!='45015'){
            self::send(["content"=>date("Y-m-d H:i:s")."\r\n公众号：".$appId."\r\n自定义菜单海报消息发送失败\r\n消息：海报\r\n". $result['errcode']. "\r\n请联系技术排查问题"]);
            MyLog::setLog(["media_id"=>$result['errcode']], '自定义菜单-发送海报', Logger::INFO, '', '', PUBLIC_PATH . '/log/'.__CLASS__.'/' . date("Ymd") . '/' . __FUNCTION__ . ".log");
            return false;
        }

        return true;
    }

    /**
     * 收到消息 自定义回复
     * @param $MsgType
     * @param string $Event
     * @param $appId
     * @param $openId
     * @return string
     */
    public function getMsg($MsgType,$Event='',$appId,$openId)
    {
        $refreshToken = $this->getRefreshToken($appId);
        if (!$refreshToken) {
            return 'success';
        }
        $officialAccount = self::$open->officialAccount($appId, $refreshToken);
        $userInfo = $this->getUserInfo($appId, $openId, $officialAccount);

        $autoReply = AutoReplyList::findFirst([
            'conditions'=>"app_id = '{$appId}' and status = 1 and category = '{$MsgType}'",
            'order'=>'id desc'
        ]);
        if($autoReply) {
            $replyContent = AutoReplyContent::find([
                'conditions' => "auto_reply_id = '{$autoReply->id}'",
                'columns' => "id,type,content",
                'order' => 'id asc'
            ]);
            $group = time().rand(10000,99999);
            if($replyContent){
                $create_time = date("Y-m-d H:i:s",time());
                $this->db->begin();
                foreach ($replyContent as $val){
                    $task = new AutoReplyTask();
                    $task->app_id = $appId;
                    $task->open_id = $openId;
                    $task->nickname = $userInfo['nickname'];
                    $task->msg_type = $val['type'];
                    $task->msg_content = $val['content'];
                    $task->group_num = $group;
                    $task->create_time = $create_time;
                    $res = $task->save();
                    if(!$res){
                        $this->db->rollback();
                        foreach ($task->getMessages() as $message) {
                            MyLog::setLog([$message->getMessage()], $appId . "自动回复计划任务添加失败", Logger::INFO, '', '', PUBLIC_PATH . '/log/sub_msg/' . $appId . "_auto_reply_task_error.log");
                        }
                    }
                }
                $this->db->commit();
            }
        }
        return 'success';
    }
}

